home *** CD-ROM | disk | FTP | other *** search
- =pod
-
- =head1 NAME
-
- autobox - call methods on native types
-
- =head1 SYNOPSIS
-
- use autobox;
-
- # integers
-
- my $range = 10->to(1); # [ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 ]
-
- # floats
-
- my $error = 3.1415927->minus(22/7)->abs();
-
- # strings
-
- my @list = 'SELECT * FROM foo'->list();
- my $greeting = "Hello, world!"->upper(); # "HELLO, WORLD!"
-
- $greeting->for_each(\&character_handler);
-
- # arrays and array refs
-
- my $schwartzian = @_->map(...)->sort(...)->map(...);
- my $hash = [ 'SELECT * FROM foo WHERE id IN (?, ?)', 1, 2 ]->hash();
-
- # hashes and hash refs
-
- { alpha => 'beta', gamma => 'vlissides' }->for_each(...);
- %hash->keys();
-
- # code refs
-
- my $plus_five = (\&add)->curry()->(5);
- my $minus_three = sub { $_[0] - $_[1] }->reverse->curry->(3);
-
- # can, isa, VERSION, import and unimport can be accessed via autobox_class
-
- 42->autobox_class->isa('MyNumber')
- say []->autobox_class->VERSION
-
- =head1 DESCRIPTION
-
- The autobox pragma allows methods to be called on integers, floats, strings, arrays,
- hashes, and code references in exactly the same manner as blessed references.
-
- The autoboxing is transparent: boxed values are not blessed into their (user-defined)
- implementation class (unless the method elects to bestow such a blessing) - they simply
- use its methods as though they are.
-
- The classes (packages) into which the native types are boxed are fully configurable.
- By default, a method invoked on a non-object is assumed to be
- defined in a class whose name corresponds to the C<ref()> type of that
- value - or SCALAR if the value is a non-reference.
-
- This mapping can be overridden by passing key/value pairs to the C<use autobox>
- statement, in which the keys represent native types, and the values
- their associated classes.
-
- As with regular objects, autoboxed values are passed as the first argument of the specified method.
- Consequently, given a vanilla C<use autobox>:
-
- "Hello, world!"->upper()
-
- is invoked as:
-
- SCALAR::upper("hello, world!")
-
- while:
-
- [ 1 .. 10 ]->for_each(sub { ... })
-
- resolves to:
-
- ARRAY::for_each([ 1 .. 10 ], sub { ... })
-
- Values beginning with the array C<@> and hash C<%> sigils are passed by reference, i.e. under the default bindings:
-
- @array->join(', ')
- @{ ... }->length()
- %hash->keys()
- %$hash->values()
-
- are equivalent to:
-
- ARRAY::join(\@array, ', ')
- ARRAY::length(\@{ ... })
- HASH::keys(\%hash)
- HASH::values(\%$hash)
-
- Multiple C<use autobox> statements can appear in the same scope. These are merged both "horizontally" (i.e.
- multiple classes can be associated with a particular type) and "vertically" (i.e. multiple classes can be associated
- with multiple types).
-
- Thus:
-
- use autobox SCALAR => 'Foo';
- use autobox SCALAR => 'Bar';
-
- - associates SCALAR types with a synthetic class whose C<@ISA> includes both C<Foo> and C<Bar> (in that order).
-
- Likewise:
-
- use autobox SCALAR => 'Foo';
- use autobox SCALAR => 'Bar';
- use autobox ARRAY => 'Baz';
-
- and
-
- use autobox SCALAR => [ 'Foo', 'Bar' ];
- use autobox ARRAY => 'Baz';
-
- - bind SCALAR types to the C<Foo> and C<Bar> classes and ARRAY types to C<Baz>.
-
- C<autobox> is lexically scoped, and bindings for an outer scope
- can be extended or countermanded in a nested scope:
-
- {
- use autobox; # default bindings: autobox all native types
- ...
-
- {
- # appends 'MyScalar' to the @ISA associated with SCALAR types
- use autobox SCALAR => 'MyScalar';
- ...
- }
-
- # back to the default (no MyScalar)
- ...
- }
-
- Autoboxing can be turned off entirely by using the C<no> syntax:
-
- {
- use autobox;
- ...
- no autobox;
- ...
- }
-
- - or can be selectively disabled by passing arguments to the C<no autobox> statement:
-
- use autobox; # default bindings
-
- no autobox qw(SCALAR);
-
- []->foo(); # OK: ARRAY::foo([])
-
- "Hello, world!"->bar(); # runtime error
-
- Autoboxing is not performed for barewords i.e.
-
- my $foo = Foo->new();
-
- and:
-
- my $foo = new Foo;
-
- behave as expected.
-
- Methods are called on native types by means of the L<arrow operator|perlop/"The Arrow Operator">. As with
- regular objects, the right hand side of the operator can either be a bare method name or a variable containing
- a method name or subroutine reference. Thus the following are all valid:
-
- sub method1 { ... }
- my $method2 = 'some_method';
- my $method3 = sub { ... };
- my $method4 = \&some_method;
-
- " ... "->method1();
- [ ... ]->$method2();
- { ... }->$method3();
- sub { ... }->$method4();
-
- A native type is only asociated with a class if the type => class mapping
- is supplied in the C<use autobox> statement. Thus the following will not work:
-
- use autobox SCALAR => 'MyScalar';
-
- @array->some_array_method();
-
- - as no class is specified for the ARRAY type. Note: the result of calling a method
- on a native type that is not associated with a class is the usual runtime error message:
-
- Can't call method "some_array_method" on unblessed reference at ...
-
- As a convenience, there is one exception to this rule. If C<use autobox> is invoked with no arguments
- (ignoring the DEBUG option) the four main native types are associated with classes of the same name.
-
- Thus:
-
- use autobox;
-
- - is equivalent to:
-
- use autobox
- SCALAR => 'SCALAR',
- ARRAY => 'ARRAY',
- HASH => 'HASH',
- CODE => 'CODE';
-
- This facilitates one-liners and prototypes:
-
- use autobox;
-
- sub SCALAR::split { [ split '', $_[0] ] }
- sub ARRAY::length { scalar @{$_[0]} }
-
- print "Hello, world!"->split->length();
-
- However, using these default bindings is not recommended as there's no guarantee that another
- piece of code won't trample over the same namespace/methods.
-
- =head1 OPTIONS
-
- A mapping from native types to their user-defined classes can be specified
- by passing a list of key/value pairs to the C<use autobox> statement.
-
- The following example shows the range of valid arguments:
-
- use autobox
- SCALAR => 'MyScalar' # class name
- ARRAY => 'MyNamespace::', # class prefix (ending in '::')
- HASH => [ 'MyHash', 'MyNamespace::' ], # one or more class names and/or prefixes
- CODE => ..., # any of the 3 value types above
- INTEGER => ..., # any of the 3 value types above
- FLOAT => ..., # any of the 3 value types above
- NUMBER => ..., # any of the 3 value types above
- STRING => ..., # any of the 3 value types above
- UNDEF => ..., # any of the 3 value types above
- UNIVERSAL => ..., # any of the 3 value types above
- DEFAULT => ..., # any of the 3 value types above
- DEBUG => ...; # boolean or coderef
-
- The INTEGER, FLOAT, NUMBER, STRING, SCALAR, ARRAY, HASH, CODE, UNDEF, DEFAULT and UNIVERSAL options can take
- three different types of value:
-
- =over
-
- =item *
-
- A class name e.g.
-
- use autobox INTEGER => 'MyInt';
-
- This binds the specified native type to the specified class. All methods invoked on
- literals or values of type C<key> will be dispatched as methods of the class specified in
- the corresponding C<value>.
-
- =item *
-
- A namespace: this is a class prefix (up to and including the final '::')
- to which the specified type name (INTEGER, FLOAT, STRING &c.) will be appended:
-
- Thus:
-
- use autobox ARRAY => 'Prelude::';
-
- is equivalent to:
-
- use autobox ARRAY => 'Prelude::ARRAY';
-
- =item *
-
- A reference to an array of class names and/or namespaces. This associates multiple classes with the
- specified type.
-
- =back
-
- =head2 DEFAULT
-
- The C<DEFAULT> option specifies bindings for any of the four default types (SCALAR, ARRAY, HASH and CODE)
- not supplied in the C<use autobox> statement. As with the other options, the C<value> corresponding to
- the C<DEFAULT> C<key> can be a class name, a namespace, or a reference to an array containing one or
- more class names and/or namespaces.
-
- Thus:
-
- use autobox
- STRING => 'MyString',
- DEFAULT => 'MyDefault';
-
- is equivalent to:
-
- use autobox
- STRING => 'MyString',
- SCALAR => 'MyDefault',
- ARRAY => 'MyDefault',
- HASH => 'MyDefault',
- CODE => 'MyDefault';
-
- Which in turn is equivalent to:
-
- use autobox
- INTEGER => 'MyDefault',
- FLOAT => 'MyDefault',
- STRING => [ 'MyString', 'MyDefault' ],
- ARRAY => 'MyDefault',
- HASH => 'MyDefault',
- CODE => 'MyDefault';
-
- Namespaces in DEFAULT values have the default type name appended, which, in the case of defaulted SCALAR types,
- is SCALAR rather than INTEGER, FLOAT &c.
-
- Thus:
-
- use autobox
- ARRAY => 'MyArray',
- HASH => 'MyHash',
- CODE => 'MyCode',
- DEFAULT => 'MyNamespace::';
-
- is equivalent to:
-
- use autobox
- INTEGER => 'MyNamespace::SCALAR',
- FLOAT => 'MyNamespace::SCALAR',
- STRING => 'MyNamespace::SCALAR',
- ARRAY => 'MyArray',
- HASH => 'MyArray',
- CODE => 'MyCode';
-
- Any of the four default types can be exempted from defaulting to the DEFAULT value by supplying a value of undef:
-
- use autobox
- HASH => undef,
- DEFAULT => 'MyDefault';
-
- 42->foo # ok: MyDefault::foo
- []->bar # ok: MyDefault::bar
-
- %INC->baz # not ok: runtime error
-
- =head2 UNDEF
-
- The pseudotype, UNDEF, can be used to autobox undefined values. These are not autoboxed by default.
-
- This doesn't work:
-
- use autobox;
-
- undef->foo() # runtime error
-
- This works:
-
- use autobox UNDEF => 'MyUndef';
-
- undef->foo(); # ok
-
- So does this:
-
- use autobox UNDEF => 'MyNamespace::';
-
- undef->foo(); # ok
-
- =head2 NUMBER, SCALAR and UNIVERSAL
-
- The virtual types NUMBER, SCALAR and UNIVERSAL function as macros or shortcuts which create
- bindings for their subtypes. The type hierarchy is as follows:
-
- UNIVERSAL -+
- |
- +- SCALAR -+
- | |
- | +- NUMBER -+
- | | |
- | | +- INTEGER
- | | |
- | | +- FLOAT
- | |
- | +- STRING
- |
- +- ARRAY
- |
- +- HASH
- |
- +- CODE
-
- Thus:
-
- use autobox NUMBER => 'MyNumber';
-
- is equivalent to:
-
- use autobox
- INTEGER => 'MyNumber',
- FLOAT => 'MyNumber';
-
- And:
-
- use autobox SCALAR => 'MyScalar';
-
- is equivalent to:
-
- use autobox
- INTEGER => 'MyScalar',
- FLOAT => 'MyScalar',
- STRING => 'MyScalar';
-
- Virtual types can also be passed to C<unimport> via the C<no autobox> syntax. This disables autoboxing
- for the corresponding subtypes e.g.
-
- no autobox qw(NUMBER);
-
- is equivalent to:
-
- no autobox qw(INTEGER FLOAT);
-
- Virtual type bindings can be mixed with ordinary bindings to provide fine-grained control over
- inheritance and delegation. For instance:
-
- use autobox
- INTEGER => 'MyInteger',
- NUMBER => 'MyNumber',
- SCALAR => 'MyScalar';
-
- would result in the following bindings:
-
- 42->foo -> [ MyInteger, MyNumber, MyScalar ]
- 3.1415927->bar -> [ MyNumber, MyScalar ]
- "Hello, world!->baz -> [ MyScalar ]
-
- Note that DEFAULT bindings take precedence over virtual type bindings i.e.
-
- use autobox
- UNIVERSAL => 'MyUniversal',
- DEFAULT => 'MyDefault'; # default SCALAR, ARRAY, HASH and CODE before UNIVERSAL
-
- is equivalent to:
-
- use autobox
- INTEGER => [ 'MyDefault', 'MyUniversal' ],
- FLOAT => [ 'MyDefault', 'MyUniversal' ], # ... &c.
-
- =head2 DEBUG
-
- C<DEBUG> exposes the current bindings for the scope in which C<use autobox> is called by means
- of a callback, or a static debugging function.
-
- This allows the computed bindings to be seen in "longhand".
-
- The option is ignored if the value corresponding to the C<DEBUG> key is false.
-
- If the value is a CODE ref, then this sub is called with a reference to
- the hash containing the computed bindings for the current scope.
-
- Finally, if C<DEBUG> is true but not a CODE ref, the bindings are dumped
- to STDERR.
-
- Thus:
-
- use autobox DEBUG => 1, ...
-
- or
-
- use autobox DEBUG => sub { ... }, ...
-
- or
-
- sub my_callback ($) {
- my $hashref = shift;
- ...
- }
-
- use autobox DEBUG => \&my_callback, ...
-
- =head1 METHODS
-
- =head2 import
-
- On its own, C<autobox> doesn't implement any methods that can be called on native types.
- However, its static method, C<import>, can be used to implement C<autobox> extensions i.e.
- lexically scoped modules that provide C<autobox> bindings for one or more native types without requiring
- calling code to C<use autobox>.
-
- This is done by subclassing C<autobox> and overriding C<import>. This allows extensions to effectively
- translate C<use MyModule> into a bespoke C<use autobox> call. e.g.:
-
- package String::Trim;
-
- use base qw(autobox);
-
- sub import {
- my $class = shift;
- $class->SUPER::import(STRING => 'String::Trim::Scalar');
- }
-
- package String::Trim::Scalar;
-
- sub trim {
- my $string = shift;
- $string =~ s/^\s+//;
- $string =~ s/\s+$//;
- $string;
- }
-
- 1;
-
- Note that C<trim> is defined in an auxiliary class rather than in C<String::Trim> itself to prevent
- C<String::Trim>'s own methods (i.e. the methods it inherits from C<autobox>) being exposed to SCALAR types.
-
- This module can now be used without a C<use autobox> statement to enable the C<trim> method in the current
- lexical scope. e.g.:
-
- #!/usr/bin/env perl
-
- use String::Trim;
-
- print " Hello, world! "->trim();
-
- =head1 EXPORTS
-
- =head2 autobox_class
-
- C<autobox> makes a single method available to autoboxed types: C<autobox_class>. This can be used to
- call C<isa>, C<can>, C<VERSION>, C<import> and C<unimport>. e.g.
-
- if (42->autobox_class->isa('SCALAR')) ...
- if (sub { ... }->autobox_class->can('curry')) ...
-
- =head2 type
-
- C<autobox> includes an additional module, C<autobox::universal>, which exports a single subroutine, C<type>.
-
- This sub returns the type of its argument within C<autobox> (which is essentially longhand for the type names
- used within perl). This value is used by C<autobox> to associate a method invocant with its designated classes. e.g.
-
- use autobox::universal qw(type);
-
- type("Hello, world!") # STRING
- type(42) # INTEGER
- type([]) # ARRAY
- type(sub { }) # CODE
-
- C<autobox::universal> is loaded automatically by C<autobox>, and, as its name suggests, can be used to install
- a universal method (i.e. a method for all C<autobox> types) e.g.
-
- use autobox UNIVERSAL => 'autobox::universal';
-
- 42->type # INTEGER
- 3.1415927->type # FLOAT
- %ENV->type # HASH
-
- =head1 CAVEATS
-
- =head2 Performance
-
- Autoboxing comes at a price. Calling
-
- "Hello, world!"->length()
-
- is slightly slower than the equivalent method call on a string-like object, and significantly slower than
-
- length("Hello, world!")
-
- =head2 Gotchas
-
- =head3 Precedence
-
- Due to Perl's precedence rules, some autoboxed literals may need to be parenthesized:
-
- For instance, while this works:
-
- my $curried = sub { ... }->curry();
-
- this doesn't:
-
- my $curried = \&foo->curry();
-
- The solution is to wrap the reference in parentheses:
-
- my $curried = (\&foo)->curry();
-
- The same applies for signed integer and float literals:
-
- # this works
- my $range = 10->to(1);
-
- # this doesn't work
- my $range = -10->to(10);
-
- # this works
- my $range = (-10)->to(10);
-
- =head3 print BLOCK
-
- Perl's special-casing for the C<print BLOCK ...> syntax (see L<perlsub>) means that C<print { expression() } ...>
- (where the curly brackets denote an anonymous HASH ref) may require some further disambiguation:
-
- # this works (
- print { foo => 'bar' }->foo();
-
- # and this
- print { 'foo', 'bar' }->foo();
-
- # and even this
- print { 'foo', 'bar', @_ }->foo();
-
- # but this doesn't
- print { @_ }->foo() ? 1 : 0
-
- In the latter case, the solution is to supply something
- other than a HASH ref literal as the first argument
- to C<print()>:
-
- # e.g.
- print STDOUT { @_ }->foo() ? 1 : 0;
-
- # or
- my $hashref = { @_ };
- print $hashref->foo() ? 1 : 0;
-
- # or
- print '', { @_ }->foo() ? 1 : 0;
-
- # or
- print '' . { @_ }->foo() ? 1 : 0;
-
- # or even
- { @_ }->print_if_foo(1, 0);
-
- =head3 eval EXPR
-
- Like most pragmas autobox performs some of its operations at compile time, and,
- as a result, runtime string C<eval>s are not executed within its scope i.e. this
- doesn't work:
-
- use autobox;
-
- eval "42->foo";
-
- The workaround is to use autobox within the C<eval> e.g.
-
- eval <<'EOS';
- use autobox;
- 42->foo();
- EOS
-
- Note that the C<eval BLOCK> form works as expected:
-
- use autobox;
-
- eval { 42->foo() }; # OK
-
- =head1 VERSION
-
- 2.70
-
- =head1 SEE ALSO
-
- =over
-
- =item * L<autobox::Core|autobox::Core>
-
- =item * L<Moose::Autobox>
-
- =item * L<perl5i|perl5i>
-
- =item * L<Scalar::Properties|Scalar::Properties>
-
- =back
-
- =head1 AUTHOR
-
- chocolateboy <chocolate@cpan.org>
-
- =head1 COPYRIGHT
-
- Copyright (c) 2003-2010, chocolateboy.
-
- This module is free software. It may be used, redistributed
- and/or modified under the same terms as Perl itself.
-
- =cut
-